package com.controller;


import com.config.TheadPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.*;

/**
 * @author: 取消正在线程池中执行的线程任务测试
 * @date: 2021/10/30 22:28
 */
@RestController
@RequestMapping("/test")
public class TheadPoolController {
    private static final Logger LOG = LoggerFactory.getLogger(TheadPoolController.class);

    @Resource(name = "syncPool")
    private ThreadPoolExecutor pool;

    private volatile Future futureTask;

    private volatile Thread thread;

    @PostMapping("/addTask")
    public String addTask(@RequestParam(required = false) boolean force) {
        if (futureTask != null && !force) {
            return "任务正在执行中";
        }
        if (force && futureTask != null) {
            futureTask.cancel(true);
            LOG.info("取消未完成任务");
        }
        int total = 100;
        futureTask = pool.submit(() -> {
            for (int i = 0; i < total; i++) {
                // 如果线程被取消则break，注意如果用Thread.sleep()之后这里不会生效，要在Thread.sleep()中的catch加上break
                if (Thread.currentThread().isInterrupted()) {
                    LOG.info("thread break {} {}", Thread.currentThread().getName(), (i + 1) + "/" + total);
                    break;
                }
                LOG.info("sync {} ,{}", (i + 1) + "/" + total, Thread.currentThread().isInterrupted());
                try {
                    // 使用了Thread.sleep()之后上面的Thread.currentThread().isInterrupted()就不生效了
                    // 注意在catch加break
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    LOG.info("Thread.sleep error", e);
                    LOG.info("thread break {} {}", Thread.currentThread().getName(), (i + 1) + "/" + total);
                    break;
                }
            }
            LOG.info("执行完成");
        });
        return "任务添加成功";
    }

    @PostMapping("/addTask1")
    public String addTask1(@RequestParam(required = false) boolean force) {
        if (!force && thread != null) {
            return "任务正在执行中";
        }
        if (force && thread != null) {
            // 设置中断线程标志
            thread.interrupt();
            LOG.info("取消未完成任务");
        }
        int total = 100;
        thread = new Thread("测试线程") {
            @Override
            public void run() {
                super.run();
                for (int i = 0; i < total; i++) {
                    // 如果线程被中断则break，注意如果用Thread.sleep()之后这里不会生效，要在Thread.sleep()中的catch加上break
                    // interrupted(),isInterrupted() https://www.cnblogs.com/w-wfy/p/6414801.html 介绍的很详细
                    if (this.isInterrupted()) {
                        LOG.info("1 thread break {} {}", Thread.currentThread().getName(), (i + 1) + "/" + total);
                        break;
                    }
                    LOG.info("sync {} ,{}", (i + 1) + "/" + total, Thread.currentThread().isInterrupted());
                    try {
                        // 使用了Thread.sleep()之后上面的Thread.currentThread().isInterrupted()就不生效了
                        // 注意在catch加break
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        LOG.info("Thread.sleep error", e);
                        LOG.info("2 thread break {} {}", Thread.currentThread().getName(), (i + 1) + "/" + total);
                        break;
                    }
                }
                LOG.info("执行完成");
            }
        };
        thread.start();
        return "任务添加成功";
    }
}
